#include <stdio.h>
#include <string.h>
#include "constant.h"

_Bool protocol_is_modbus(protocol_e type) {
    return cp_modbus_rtu == type || cp_modbus_tcp == type;
}

_Bool protocol_is_dlt645(protocol_e type) {
    return cp_dlt645_07 == type || cp_dlt645_97 == type;
}

_Bool channel_is_serial(channel_type_e type) {
    return ct_serial == type || ct_rs232 == type || ct_rs485 == type;
}

int get_data_len(data_type_e dt) {
    switch (dt) {
        case dt_long:
        case dt_neg_long:
        case dt_qword:
        case dt_double:
            return 4;
        case dt_mid:
        case dt_neg_mid:
        case dt_tword:
            return 3;
        case dt_integer:
        case dt_neg_int:
        case dt_dword:
        case dt_float:
            return 2;
        default:
            return 1;
    }
}

data_catalog_e get_data_catalog(const char *str) {
    if (0 == strcmp("none", str)) {
        return dc_none;
    } else if (0 == strcmp("analog", str)) {
        return dc_analog;
    } else if (0 == strcmp("power", str)) {
        return dc_power;
    } else if (0 == strcmp("energy", str)) {
        return dc_energy;
    } else if (0 == strcmp("demand", str)) {
        return dc_demand;
    } else if (0 == strcmp("harmonic", str)) {
        return dc_harmonic;
    } else if (0 == strcmp("harmonic_odd", str)) {
        return dc_harmonic_odd;
    } else if (0 == strcmp("harmonic_even", str)) {
        return dc_harmonic_even;
    } else if (0 == strcmp("param", str)) {
        return dc_param;
    } else if (0 == strcmp("param_ex", str)) {
        return dc_param_ex;
    } else if (0 == strcmp("period", str)) {
        return dc_hourly;
    } else if (0 == strcmp("daily", str)) {
        return dc_daily;
    } else if (0 == strcmp("bit", str)) {
        return dc_bit;
    } else if (0 == strcmp("soe", str)) {
        return dc_soe;
    } else if (0 == strcmp("event", str)) {
        return dc_event;
    } else {
        printf("invalid data_catalog '%s', use default 'none'\n", str);
        return dc_none;
    }
}

data_type_e get_data_type(const char *str) {
    if (0 == strcmp("bit", str)) {
        return dt_bit;
    } else if (0 == strcmp("byte", str)) {
        return dt_byte;
    } else if (0 == strcmp("short", str)) {
        return dt_short;
    } else if (0 == strcmp("neg_short", str)) {
        return dt_neg_short;
    } else if (0 == strcmp("word", str)) {
        return dt_word;
    } else if (0 == strcmp("mid", str)) {
        return dt_mid;
    } else if (0 == strcmp("neg_mid", str)) {
        return dt_neg_mid;
    } else if (0 == strcmp("tword", str)) {
        return dt_tword;
    } else if (0 == strcmp("integer", str)) {
        return dt_integer;
    } else if (0 == strcmp("neg_int", str)) {
        return dt_neg_int;
    } else if (0 == strcmp("dword", str)) {
        return dt_dword;
    } else if (0 == strcmp("long", str)) {
        return dt_long;
    } else if (0 == strcmp("neg_long", str)) {
        return dt_neg_long;
    } else if (0 == strcmp("qword", str)) {
        return dt_qword;
    } else if (0 == strcmp("float", str)) {
        return dt_float;
    } else if (0 == strcmp("double", str)) {
        return dt_double;
    } else {
        fprintf(stderr, "invalid data_type '%s', use default 'word'\n", str);
        return dt_word;
    }
}

time_type_e get_time_type(const char *str) {
    if (0 == strcmp("ymd", str)) {
        return tt_ymd;
    } else if (0 == strcmp("y4md", str)) {
        return tt_y4md;
    } else if (0 == strcmp("hns", str)) {
        return tt_hns;
    } else if (0 == strcmp("ymdhns", str)) {
        return tt_ymdhns;
    } else if (0 == strcmp("y4mdhns", str)) {
        return tt_y4mdhns;
    } else {
        return tt_none;
    }
}

writable_e get_writable(const char *str) {
    if (0 == strcmp("rw", str)) {
        return read_write;
    } else if (0 == strcmp("ro", str)) {
        return read_only;
    } else if (0 == strcmp("wo", str)) {
        return write_only;
    } else {
        fprintf(stderr, "invalid writable '%s', use default 'ro'\n", str);
        return read_only;
    }
}

char *replace_metric(char *metric, size_t size) {
    if (!metric) return NULL;

    char *p = metric;
    for (int i = 0; *p != '\0' && i < size; ++i, ++p) {
        if (*p == '.') {
            *p = '_';
        }
    }

    return metric;
}